#ifndef __ATMOS_AutoHandler_h__
#define __ATMOS_AutoHandler_h__

#include "ATMOS_Common.h"

#include <map>

namespace ATMOS {

	/*! This template class provides a child class with the means to register a suite of methods
	 * that are called according to the given index type.
	 \param BASE the name of the class that is inheriting from AutoHandler
	 \param ARG_TYPE the type of the argument passed to the handler functions
	 \param RET_TYPE the type returned by handler functions
	 \param INDEX_TYPE the type of the index by which handler functions stored
	 */
	template <typename BASE,typename ARG_TYPE,typename RET_TYPE,typename INDEX_TYPE>
	class AutoHandler
	{
	protected:
		typedef RET_TYPE(BASE::*HandlerFunction)(ARG_TYPE);
		typedef std::map<INDEX_TYPE,HandlerFunction> HandlerFunctionMap;

		HandlerFunctionMap mHandlerFunctions;

		void registerHandler( INDEX_TYPE index, HandlerFunction function )
		{
			mHandlerFunctions.insert( std::make_pair( index, function ) );
		}

		void unregisterHandler( INDEX_TYPE index )
		{
			mHandlerFunctions.erase( mHandlerFunctions.find( index ) );
		}

	public:
		RET_TYPE handle( INDEX_TYPE index, ARG_TYPE arg )
		{
		#if(ATMOS_PLATFORM == ATMOS_PLATFORM_LINUX)
		    HandlerFunction func = mHandlerFunctions[index];
		    if( func == 0 )
		    {
		        ATMOS_THROW_RT("handler method is null");
		    }
            return (*static_cast<BASE*>(this).*func)( arg );
        #else
			//HandlerFunctionMap::iterator iter = mHandlerFunctions.find( index );
			std::map<INDEX_TYPE,HandlerFunction>::iterator iter = mHandlerFunctions.find( index );
			if( iter != mHandlerFunctions.end() )
			{
				HandlerFunction func = iter->second;
				return (*static_cast<BASE*>(this).*func)( arg );
			}
        #endif
		}
	};

} // end namespace ATMOS

#endif
